home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.misc
- From: Ajay Shah <ajayshah@alhena.usc.edu>
- Subject: v21i043: mailmerge - Mailmerge written in awk, Part01/01
- Message-ID: <1991Jul26.181156.26871@sparky.IMD.Sterling.COM>
- X-Md4-Signature: 5dc6e660cb608e64b8eb18aead5d872e
- Date: Fri, 26 Jul 1991 18:11:56 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: Ajay Shah <ajayshah@alhena.usc.edu>
- Posting-number: Volume 21, Issue 43
- Archive-name: mailmerge/part01
- Environment: AWK
-
- This is a mailmerge program. It is not aware of the typesetter
- being used; i.e., it can work with troff, TeX, or whatever.
- I searched on archie, and only turned up one such program, which
- seemed to be rather troff-oriented.
-
- It takes two inputs:
-
- - a letter written using variables of the form NAME
- - a database of people, which is just values for these variables.
-
- Suppose the letter is in a file named "letter". Suppose
- the database is in a file "list.of.people". The command
-
- gawk -f mailmerge.awk -v L=letter list.of.people
-
- will generate files mm_letter.1, mm_letter.2, etc in current
- directory.
-
- The file demo.letter is a sample of a letter. The use of mailmerge
- variables MUST be of the form FIELD, though uppercase is optional.
- As long as the fieldname you use agrees with the corresponding
- name in the datafile (including case) it will work out right.
-
- If you're afraid about a field name clashing with something
- which should not be replaced, you could always use a fieldname
- of the form _NAME instead of NAME. That should make clashes
- practically impossible.
-
- The file demo.db is a sample database file. The first line
- MUST define the layout of fields on the line. The fields MUST
- be pipe-delimited. Extra blank lines anywhere are ok.
-
- To test it on these demo files, doublecheck that the top of
- the Makefile is ok, and say "make".
-
- Ajay_Shah@rand.org
- Ajay Shah,
- The Rand Corporation,
- Thu Jul 25 21:46:02 PDT 1991
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: 1.expected 2.expected Makefile README demo.db demo.letter
- # mailmerge.awk
- # Wrapped by ajayshah@max on Thu Jul 25 21:47:43 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f '1.expected' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'1.expected'\"
- else
- echo shar: Extracting \"'1.expected'\" \(99 characters\)
- sed "s/^X//" >'1.expected' <<'END_OF_FILE'
- X
- XTo
- X Sadhana Shah
- X CMIE, Bombay
- X
- XDear Sad,
- X
- X I almost forgot that July 8 was your birthday!
- X
- X - me
- END_OF_FILE
- if test 99 -ne `wc -c <'1.expected'`; then
- echo shar: \"'1.expected'\" unpacked with wrong size!
- fi
- # end of '1.expected'
- fi
- if test -f '2.expected' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'2.expected'\"
- else
- echo shar: Extracting \"'2.expected'\" \(106 characters\)
- sed "s/^X//" >'2.expected' <<'END_OF_FILE'
- X
- XTo
- X Susan Thomas
- X Rand Corporation
- X
- XDear Susan,
- X
- X I almost forgot that July 30 was your birthday!
- X
- X - me
- END_OF_FILE
- if test 106 -ne `wc -c <'2.expected'`; then
- echo shar: \"'2.expected'\" unpacked with wrong size!
- fi
- # end of '2.expected'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(469 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X
- XNEWAWK=gawk
- X # change that to be your copy of a new awk.
- X
- X#------------------------- Need not change anything below this line
- X
- Xtest :
- X $(NEWAWK) -f mailmerge.awk -v L=demo.letter demo.db
- X diff mm_demo.letter.1 1.expected
- X diff mm_demo.letter.2 2.expected
- X @echo If those two diffs went by fine, it works.
- X
- Xclean :
- X rm -f mm_demo.letter.* readytopost
- X
- Xpost : clean
- X shar * > /tmp/mailmerge.shar
- X cat README /tmp/mailmerge.shar > readytopost
- X rm -f /tmp/mailmerge.shar
- X
- END_OF_FILE
- if test 469 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(1438 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- X
- XThis is a mailmerge program. It is not aware of the typesetter
- Xbeing used; i.e., it can work with troff, TeX, or whatever.
- XI searched on archie, and only turned up one such program, which
- Xseemed to be rather troff-oriented.
- X
- XIt takes two inputs:
- X
- X - a letter written using variables of the form NAME
- X - a database of people, which is just values for these variables.
- X
- XSuppose the letter is in a file named "letter". Suppose
- Xthe database is in a file "list.of.people". The command
- X
- X gawk -f mailmerge.awk -v L=letter list.of.people
- X
- Xwill generate files mm_letter.1, mm_letter.2, etc in current
- Xdirectory.
- X
- XThe file demo.letter is a sample of a letter. The use of mailmerge
- Xvariables MUST be of the form FIELD, though uppercase is optional.
- XAs long as the fieldname you use agrees with the corresponding
- Xname in the datafile (including case) it will work out right.
- X
- XIf you're afraid about a field name clashing with something
- Xwhich should not be replaced, you could always use a fieldname
- Xof the form _NAME instead of NAME. That should make clashes
- Xpractically impossible.
- X
- XThe file demo.db is a sample database file. The first line
- XMUST define the layout of fields on the line. The fields MUST
- Xbe pipe-delimited. Extra blank lines anywhere are ok.
- X
- XTo test it on these demo files, doublecheck that the top of
- Xthe Makefile is ok, and say "make".
- X
- XAjay_Shah@rand.org
- XAjay Shah,
- XThe Rand Corporation,
- XThu Jul 25 21:46:02 PDT 1991
- END_OF_FILE
- if test 1438 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'demo.db' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'demo.db'\"
- else
- echo shar: Extracting \"'demo.db'\" \(121 characters\)
- sed "s/^X//" >'demo.db' <<'END_OF_FILE'
- X#LAYOUT FIRSTNAME NAME BIRTHDAY ADDRESS
- XSad|Sadhana Shah|July 8|CMIE, Bombay
- XSusan|Susan Thomas|July 30|Rand Corporation
- END_OF_FILE
- if test 121 -ne `wc -c <'demo.db'`; then
- echo shar: \"'demo.db'\" unpacked with wrong size!
- fi
- # end of 'demo.db'
- fi
- if test -f 'demo.letter' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'demo.letter'\"
- else
- echo shar: Extracting \"'demo.letter'\" \(94 characters\)
- sed "s/^X//" >'demo.letter' <<'END_OF_FILE'
- X
- XTo
- X NAME
- X ADDRESS
- X
- XDear FIRSTNAME,
- X
- X I almost forgot that BIRTHDAY was your birthday!
- X
- X - me
- END_OF_FILE
- if test 94 -ne `wc -c <'demo.letter'`; then
- echo shar: \"'demo.letter'\" unpacked with wrong size!
- fi
- # end of 'demo.letter'
- fi
- if test -f 'mailmerge.awk' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mailmerge.awk'\"
- else
- echo shar: Extracting \"'mailmerge.awk'\" \(1743 characters\)
- sed "s/^X//" >'mailmerge.awk' <<'END_OF_FILE'
- X
- XBEGIN {
- X # recall variable L has been setup.
- X # first, we swallow the file L into the (integer indexed) array
- X # "let_lines". The variable "line" contains the number of
- X # lines in this file, at the end.
- X line = 0;
- X do {
- X eof = getline s < L;
- X if (eof > 0) {
- X line++;
- X let_lines[line] = s;
- X }
- X } while (eof > 0);
- X if (line == 0) {
- X print "mailmerge.awk: File " L " does not exist." > "/dev/tty";
- X goch = 1; exit 1;
- X }
- X}
- X
- X{taken = 0}
- X # "This line has not yet been dealt with.
- X
- X(NF == 0) {taken = 1}
- X # Ignore blank lines (i.e., those with no fields).
- X
- X# Now catch the LAYOUT line:
- X/^#LAYOUT/ {
- X taken = 1;
- X if (NF == 1) {
- X print "mailmerge.awk: LAYOUT must contain some fields!" > "/dev/tty";
- X goch = 1; exit 1;
- X }
- X for (i=2; i<=NF; i++) position[$i] = i-1;
- X fnum = NF-1;
- X # just gobble layout into "position" associative array.
- X gotlayout = 1;
- X}
- X
- X# Finally, if you have a line with taken == 0, it's a normal DB line.
- X(taken == 0) {
- X if (gotlayout == 0) {
- X print "mailmerge.awk: Database file must contain a LAYOUT line before any real data." > "/dev/tty";
- X goch = 1; exit 1;
- X }
- X
- X print "";
- X print "Input line = " substr($0, 1, 50) " ...";
- X
- X n = split($0, words, "|");
- X if (n != fnum) {
- X print "mailmerge.awk: Error on Line " NR " of database" > "/dev/tty";
- X print " (Expect " fnum " fields, got " n ")" > "/dev/tty";
- X }
- X
- X # Now we're all set to generate code.
- X # First generate filename.
- X ofn = "mm_" L "." (NR-1);
- X print "Generating file named " ofn;
- X
- X # run over lines of letter, doing find-replace.
- X for (i=1; i<=line; i++) {
- X s = let_lines[i];
- X for (v in position)
- X if (0 != index(s, v)) # only try replace if it matches
- X gsub(v, words[position[v]], s);
- X print s > ofn;
- X }
- X}
- X
- XEND {
- X if (goch == 1) exit 1;
- X}
- END_OF_FILE
- if test 1743 -ne `wc -c <'mailmerge.awk'`; then
- echo shar: \"'mailmerge.awk'\" unpacked with wrong size!
- fi
- # end of 'mailmerge.awk'
- fi
- echo shar: End of shell archive.
- exit 0
-
- --
- _______________________________________________________________________________
- Ajay Shah, (213)734-3930, ajayshah@usc.edu
- The more things change, the more they stay insane.
- _______________________________________________________________________________
-
- exit 0 # Just in case...
-